#include <SoftwareSerial.h>
//  自动连接之前wifi，如果连接失败重新按代码里的配置连接
// 定义软串口：D2=接收（RX），D3=发送（TX），与模块接线对应
SoftwareSerial moduleSerial(2, 3);  // 软串口对象，专门与模块通信


// WiFi 配置信息（替换为你的实际信息）
const char* wifiSSID = "USART";
const char* wifiPassword = "13579asdfg";
const char* pingTarget = "www.baidu.com";  // 测试目标（百度）

 
void setup() {
  // 初始化硬件串口（仅与电脑通信，调试用）
  Serial.begin(115200);
  // 初始化软串口（仅与模块通信，波特率先试9600，不行再换）
  moduleSerial.begin(115200);
 
  Serial.println("软串口隔离通信已启动，等待指令...");
  pingTest(pingTarget);
   ensureWiFiConnected();
}
 
void loop() {
  // 1. 电脑→Arduino→模块：转发串口监视器指令到模块
  if (Serial.available()) {  // 检测电脑发送的指令
    char cmd = Serial.read();  // 读取1个字符
    moduleSerial.write(cmd);   // 通过软串口发送给模块
  }
 
  // 2. 模块→Arduino→电脑：转发模块响应到串口监视器
  if (moduleSerial.available()) {  // 检测模块发送的响应
    char response = moduleSerial.read();  // 读取1个字符
    Serial.write(response);               // 通过硬件串口发送给电脑
  }
}




/**
 * 核心函数：确保WiFi连接（基于你的pingTest函数）
 * 逻辑：Ping成功→确认连接；Ping失败→重新连接并二次验证
 */
void ensureWiFiConnected() {
  delay(6000);
  if (pingTest(pingTarget)) {
    Serial.println("✅ WiFi连接正常（Ping验证通过）");
  } else {
    Serial.println("❌ Ping失败，WiFi连接异常，开始重新连接...");
    // 执行重新连接
    if (reconnectWiFi()) {
       delay(6000);
      Serial.println("✅ 重新连接成功，再次验证...");
      // 重连后二次Ping验证
      if (pingTest(pingTarget)) {
         delay(6000);
        Serial.println("✅ 二次验证通过，WiFi已恢复");
      } else {
         delay(6000);
        Serial.println("❌ 二次验证失败，WiFi仍异常");
      }
    } else {
      Serial.println("❌ 重新连接失败，请检查WiFi信息或硬件");
    }
  }
}

/**
 * 重新连接WiFi（使用AT+WJAP指令）
 * 返回：true=连接成功，false=连接失败
 */
bool reconnectWiFi() {
  // 拼接连接指令：AT+WJAP="SSID","密码"
  String cmd = "AT+WJAP=\"" + String(wifiSSID) + "\",\"" + String(wifiPassword) + "\"";
  sendCommand(cmd);
  Serial.print("发送连接指令：");
  Serial.println(cmd);

  // 等待连接结果（超时5秒）
  unsigned long timeout = millis();
  while (millis() - timeout < 5000) {
    if (moduleSerial.find("CONNECTED") && moduleSerial.find("GOT IP")) {
      Serial.println("连接成功");
      return true; // 连接成功
    }
    if (moduleSerial.find("FAIL")) {
      Serial.println("连接失败，3秒后重试...");
      delay(3000);
      sendCommand(cmd); // 重试
      timeout = millis(); // 重置超时
    }
  }
  return false; // 超时失败
}


// 简化版Ping测试：只判断是否收到OK
bool pingTest(const char* target) {
  Serial.print("正在Ping ");
  Serial.println(target);

  // 发送Ping指令
  String cmd = "AT+PING=";
  cmd += target;
  cmd += ",3";
  sendCommand(cmd);

  // 等待响应（超时3秒）
  unsigned long timeout = millis();
  while (millis() - timeout < 3000) {
    if (moduleSerial.available() && moduleSerial.find("OK")) {
      return true; // 收到OK，判定成功
    }
  }
  return false; // 超时未收到OK，判定失败
}

// 字节级发送指令（逐字节写入）
void sendCommand(String cmd) {
  for (int i = 0; i < cmd.length(); i++) {
    moduleSerial.write(cmd[i]);  // 逐个字节发送
  }
  moduleSerial.write('\r');  // 指令结尾添加回车换行
  moduleSerial.write('\n');
}